﻿using System;
using System.Reflection;

namespace Inkubator.Wizard.WebWizard.WizardUtilities
{
    /// <summary>
    /// This class provides the capability to execute a DLL/EXE that
    /// is called dinamically.
    /// </summary>
    public class ActionInvoker
    {
        /// <summary>
        /// This method execute a DLL/EXE that match with the assemblyName,
        /// contain the method received as argument and implement the impInterface.
        /// </summary>
        /// <param name="assemblyName"></param>
        /// <param name="method"></param>
        /// <param name="impInterface"></param>
        /// <param name="arguments"></param>
        public static void invokeProcess(string assemblyName,
            string method, string impInterface, object[] arguments)
        {
            Assembly assembly = Assembly.LoadFrom(assemblyName);

            // Exploro cada tipo dentro del assembly
            foreach (Type type in assembly.GetTypes())
            {

                if (type.IsClass == true)
                {
                    //Si no implementa la interfaz que se paso como
                    //parametro, salteo esa clase.
                    if (type.GetInterface(impInterface) == null)
                    {
                        continue;
                    }

                    // En cambio, si implementa la interfaz
                    // creo una instancia del objeto
                    object implementObject = Activator.CreateInstance(type);
                    object[] argumentsInvok = new object[] { arguments };

                    //Invoco dinamicamente el metodo pasado por parametro
                    object result;
                    result = type.InvokeMember(method, 
                                                BindingFlags.Default | BindingFlags.InvokeMethod,
                                                null, implementObject, argumentsInvok);
                }
            }
        }

        /// <summary>
        /// This method execute a DLL/EXE that match with the assemblyName,
        /// contain the method received as argument and implement the impInterface and
        /// return a boolean value to determine what is the result of the execution.
        /// </summary>
        /// <param name="assemblyName"></param>
        /// <param name="method"></param>
        /// <param name="impInterface"></param>
        /// <param name="arguments"></param>
        /// <returns></returns>
        public static bool evaluateProcess(string assemblyName,
            string method, string impInterface, object[] arguments)
        {
            Assembly assembly = Assembly.LoadFrom(assemblyName);

            // Exploro cada tipo dentro del assembly
            foreach (Type type in assembly.GetTypes())
            {

                if (type.IsClass == true)
                {
                    //Si no implementa la interfaz que se paso como
                    //parametro, salteo esa clase.
                    if (type.GetInterface(impInterface) == null)
                    {
                        continue;
                    }

                    // En cambio, si implementa la interfaz
                    // creo una instancia del objeto
                    object implementObject = Activator.CreateInstance(type);

                    //Invoco dinamicamente el metodo pasado por parametro
                    object result;
                    result = type.InvokeMember(method,
                                                BindingFlags.Default | BindingFlags.InvokeMethod,
                                                null, implementObject, arguments);

                    return ((bool)result);
                }
            }

            return false;
        }

    }
}
